package eva.savant.business.ventas.view

import eva.savant.business.ventas.service.TSPedido
import eva.savant.businessobject.mt.*
import eva.savant.businessobject.vt.*
import org.primefaces.event.SelectEvent

import javax.annotation.PostConstruct
import javax.faces.bean.ManagedBean
import javax.faces.bean.SessionScoped
import javax.faces.convert.Converter

@SessionScoped
@ManagedBean(name = 'ITPedido')
public class ITPedido extends Bean {

  def XMaterialCod ='', report, sum

  PedidoDetalle detalle

  Date dateIni, dateEnd

  TSPedido tsPedido

  @PostConstruct
  public void cleanEntity() {

    dateIni= dateIni==null? new Date() : dateIni

    dateEnd= dateEnd==null? new Date() : dateEnd

    def f= entity != null? entity.fecha : new Date()

    focus= 'ps:materialId:valueId'

    entity= new Pedido(); init()

    entity.estado= 'P'

    entity.fecha= f

    entity.entrega= f

    entity.cliente= new Cliente()

    entity.lsPedidoDetalle= new ArrayList<PedidoDetalle>()

    entity.prevendedor= get(Prevendedor,'persona.id=?',usuario.persona.id)


    XMaterialCod= null

    detalle= new PedidoDetalle()

    detalle.material= new Material()


    tsPedido= (TSPedido) getSpringBean('tsPedido')


    if(entity.prevendedor == null) addErrorMessage 'El usuario actual no es prevendedor'
  }

  public List findLsEntity() {

    dateIni= toStartDay(dateIni); dateEnd= toMidnight(dateEnd)

    sum= get(Pedido,'sum(importe), sum(descuento), sum(total): fecha between ? and ?', dateIni, dateEnd)

    sum[0]= round(sum[0],2); sum[1]= round(sum[1],2); sum[2]= round(sum[2],2)

    return find(Pedido,'fecha between ? and ? order by id desc', dateIni, dateEnd)
  }

  public void editEntity(Object id) {

    entity= get(Pedido,id)
  }

  public void XMaterialFind() {

    detalle.material= get(Material.class,'rapido=?',toInteger(XMaterialCod))

    if(detalle.material == null) detalle.material= get(Material.class, sociedad.id + XMaterialCod)

    if(detalle.material == null) detalle.material= get(Material.class,'barras=?', XMaterialCod)

    if(detalle.material != null) XMaterialSelect() else focus= 'hd:gId:input'
  }

  public void XMaterialSelect() {

    focus= 'ps:cantidadId:valueId'

    XMaterialCod= detalle.material.codigo


    def p= get(Precio,'canal.id=? and material.id=?',entity.cliente.canal.id,detalle.material.id)


    detalle.precio   = p?.precio    > 0? p.precio    : 0

    detalle.impuesto = p?.impuesto  > 0? p.impuesto  : 0

    detalle.descuento= p?.descuento > 0? p.descuento : 0

    if(p == null)

    addErrorMessage 'El canal ' + entity.cliente.canal.codigo + ' no tiene el material ' + detalle.material.codigo
  }

  public void detailAddCal(Boolean isNew) {

    if(!(detalle.precio > 0)) { addErrorMessage 'El precio del producto debe ser mayor a cero'; return; }

    if(detalle.cantidad < 1) { addErrorMessage 'La cantidad de producto debe ser mayor a cero'; return; }


    def d= new PedidoDetalle()

    d.material  = detalle.material

    d.solicitado= isNew? detalle.cantidad : detalle.solicitado

    d.devuelto  = isNew? 0                : detalle.devuelto

    d.cantidad  = isNew? detalle.cantidad : d.solicitado - d.devuelto

    d.precio    = detalle.precio

    d.importe   = d.cantidad * d.precio

    d.impuesto  = d.cantidad * detalle.impuesto

    d.descuento = d.cantidad * detalle.descuento

    d.total     = (d.importe - d.descuento) + d.impuesto


    detailDelete(d); entity.lsPedidoDetalle.add(d); calculateSummary()


    detalle= new PedidoDetalle()

    detalle.material= new Material()

    XMaterialCod= ''

    focus= 'ps:materialId:valueId'
  }

  public void detailAdd() {

    detailAddCal(true)
  }

  public void detailDevAdd() {

    if(detalle.cantidad <= 0)

    for(x in entity.lsPedidoDetalle) {

    if(x.material.codigo.equalsIgnoreCase(detalle.material.codigo)) {

    detalle.cantidad= detalle.solicitado= x.solicitado; break }     }


    detailAddCal(false)
  }

  public boolean mergeEntity(Object entity) { alta((Pedido)entity); entity= (Pedido) entity

    if(entity.lsPedidoDetalle?.size() < 1) { addErrorMessage 'El detalle de productos esta vacio'; return false }

    if(!entity.estado.equalsIgnoreCase('P')) { addErrorMessage 'El pedido ya fue procesado'; return false }

    def pedido = tsPedido.save(entity)

    addInfoMessage 'El pedido fue registrado en la transaccion ' + pedido?.id; return pedido != null
  }

  public void detailEdit(SelectEvent event) {

    if(isRead) return

    def x             = (PedidoDetalle) event.object

    detalle           = new PedidoDetalle()

    detalle.material  = x.material

    detalle.solicitado= x.solicitado

    detalle.devuelto  = x.devuelto

    detalle.cantidad  = x.cantidad

    detalle.precio    = x.precio

    detalle.impuesto  = x.impuesto

    detalle.descuento = x.descuento

    detalle.importe   = x.importe

    detalle.total     = x.total

    XMaterialCod      = x.material.codigo
  }

  public void detailDelete(PedidoDetalle detalle) {

    for(int i=0; i < entity.lsPedidoDetalle.size(); i++)  { def d= entity.lsPedidoDetalle.get(i)

    if(d.material.id.equalsIgnoreCase(detalle.material.id)) { entity.lsPedidoDetalle.remove(i); break } }

    calculateSummary()
  }

  public void calculateSummary() {

    entity.importe   = 0

    entity.impuesto  = 0

    entity.descuento = 0

    entity.total     = 0


    for(detalle in entity.lsPedidoDetalle) {

    entity.importe   = entity.importe   + detalle.importe

    entity.impuesto  = entity.impuesto  + detalle.impuesto

    entity.descuento = entity.descuento + detalle.descuento

    entity.total     = entity.total     + detalle.total  }
  }

  public void actionPrint() {

    report= reportService.reportToTXT('notaPedido',['pedidoId':entity.id,'moneda':'Bolivianos'])

    report= report.replaceAll("\n","\\|")
  }

  public void cleanPrint() { report= null }

  def getXMaterialConverter() { return converterLike(Material) }

  def XMaterialComplete(String value) { return completeLike(Material,'nombre',value) }

  public List complete(String value) { return completeLike(Cliente,'persona.nombre',value) }

  public Converter getConverter() { return converterLike(Cliente) }

  public void selectCliente() { entity.glosa= 'Dir. ' + entity.cliente.persona.direccion }

}
